﻿using BCCommon;
using BCCommon.Enums;
using BCData.Trading.SaleGoods.SaleGoodsCategory;
using BCDto.Trading.SaleGoods.SaleGoodsCategory;
using BCEntity.Trading.SaleGoods.SaleGoodsCategory;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BCCommon.NPinyin;
using BCData.Trading.SaleGoods.SaleGoods;

namespace BCService.Trading.SaleGoods.SaleGoodsCategory
{
    public class SaleGoodsCategoryService : ISaleGoodsCategoryService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IApplicationContextService applicationContextService;
        private readonly IRedisService redisService;
        private readonly ISaleGoodsCategoryData saleGoodsCategoryData;
        private readonly ISaleGoodsData saleGoodsData;
        private readonly string key = string.Format("{0}", EntityNameConst.SaleGoodsCategoryEntity);

        public SaleGoodsCategoryService(IDatabaseContext databaseContext,
            IApplicationContextService applicationContextService,
            IRedisService redisService,
            ISaleGoodsCategoryData saleGoodsCategoryData,
            ISaleGoodsData saleGoodsData)
        {
            this.databaseContext = databaseContext;
            this.applicationContextService = applicationContextService;
            this.redisService = redisService;
            this.saleGoodsCategoryData = saleGoodsCategoryData;
            this.saleGoodsData = saleGoodsData;
        }

        #region 检查销售商品分类是否存在
        public bool Exists(long saleGoodsCategoryId)
        {
            return this.saleGoodsCategoryData.Exists(saleGoodsCategoryId).GetAwaiter().GetResult();
        }
        #endregion

        #region 添加销售商品分类
        public SaleGoodsCategoryDto Add(SaleGoodsCategoryRequestDto requestDto)
        {
            string path = "0";
            int level = 1;
            if (requestDto.ParentId.HasValue)
            {
                if (!this.Exists(requestDto.ParentId.Value))
                {
                    throw new ArgumentException("此父级分类不存在!");
                }
                var parentEntity = this.saleGoodsCategoryData.GetEntity(requestDto.ParentId.Value).Result;
                path = parentEntity.TreePath;
                level = parentEntity.Level + 1;
            }
            var entity = requestDto.As<SaleGoodsCategoryEntity>();
            entity.TreePath = path;
            entity.CategoryNamePinyin = Pinyin.GetCompactPinyin(entity.CategoryName);
            entity.Level = level;
            entity.CreateAdminName = applicationContextService.Admin.FullName;
            entity.CreateAdminId = applicationContextService.Admin.AdminId;
            databaseContext.BeginTransaction();
            var createdEntity = this.saleGoodsCategoryData.Add(entity).Result;
            createdEntity.TreePath = requestDto.ParentId.HasValue ? string.Concat(path, ",", createdEntity.SaleGoodsCategoryId) : createdEntity.SaleGoodsCategoryId.ToString();
            var result = this.saleGoodsCategoryData.Update(createdEntity).Result;
            databaseContext.Commit();
            return result.As<SaleGoodsCategoryDto>();
        }
        #endregion

        #region 修改销售商品分类
        public SaleGoodsCategoryDto Update(SaleGoodsCategoryPutDto putDto)
        {
            string path = string.Empty;
            int level = 1;
            if (!this.Exists(putDto.SaleGoodsCategoryId))
            {
                throw new ArgumentException("此记录不存在!");
            }

            if (putDto.ParentId.HasValue)
            {
                if (!this.Exists(putDto.ParentId.Value))
                {
                    throw new ArgumentException("此父级分类不存在!");
                }
                if (this.saleGoodsCategoryData.ChildrenExists(putDto.SaleGoodsCategoryId).Result)
                {
                    throw new ArgumentException("此分类已存在子级分类，无法修改分类的父级所属!");
                }
                var parentEntity = this.saleGoodsCategoryData.GetEntity(putDto.ParentId.Value).Result;
                path = parentEntity.TreePath;
                level = parentEntity.Level + 1;
            }

            var oldEntity = this.saleGoodsCategoryData.GetEntity(putDto.SaleGoodsCategoryId).Result;

            if (this.saleGoodsData.CategoryExists(oldEntity.SaleGoodsCategoryId).Result)
            {
                if (putDto.ParentId != oldEntity.ParentId)
                {
                    throw new ArgumentException("此分类已存在销售商品，无法修改此分类的父级所属!");
                }
            }

            var entity = putDto.As<SaleGoodsCategoryEntity>();
            entity.CategoryNamePinyin = Pinyin.GetCompactPinyin(entity.CategoryName);
            entity.TreePath = putDto.ParentId.HasValue ? string.Concat(path, ",", oldEntity.SaleGoodsCategoryId) : oldEntity.TreePath;
            entity.Level = putDto.ParentId.HasValue ? level : oldEntity.Level;
            entity.GoodsCount = oldEntity.GoodsCount;
            entity.SearchLevel = oldEntity.SearchLevel;
            entity.EditAdminName = applicationContextService.Admin.FullName;
            entity.EditAdminId = applicationContextService.Admin.AdminId;

            var result = this.saleGoodsCategoryData.Update(entity).Result.As<SaleGoodsCategoryDto>();

            string cacheKey = this.redisService.GetKey(key, entity.SaleGoodsCategoryId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 删除销售商品分类
        public bool Delete(long saleGoodsCategoryId)
        {
            if (!this.Exists(saleGoodsCategoryId))
            {
                throw new ArgumentException("此记录不存在!");
            }

            if (this.saleGoodsCategoryData.ChildrenExists(saleGoodsCategoryId).Result)
            {
                throw new ArgumentException("此分类已存在子级分类，无法删除此分类!");
            }

            var oldEntity = this.saleGoodsCategoryData.GetEntity(saleGoodsCategoryId).Result;

            if (this.saleGoodsData.CategoryExists(oldEntity.SaleGoodsCategoryId).Result)
            {
                throw new ArgumentException("此分类已存在销售商品，无法删除此分类!");
            }

            var result = this.saleGoodsCategoryData.Delete(saleGoodsCategoryId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, saleGoodsCategoryId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 获取销售商品分类
        public SaleGoodsCategoryDto Get(long saleGoodsCategoryId)
        {
            string cacheKey = this.redisService.GetKey(key, saleGoodsCategoryId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.saleGoodsCategoryData.GetEntity(saleGoodsCategoryId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromMinutes(30));
            return result.As<SaleGoodsCategoryDto>();
        }
        #endregion

        #region 获取销售商品分类列表
        public IEnumerable<SaleGoodsCategoryDto> GetList()
        {
            var result = this.redisService.TryGet(key, () =>
            {
                return this.saleGoodsCategoryData.GetList().GetAwaiter().GetResult();
            }, TimeSpan.FromMinutes(30));
            return result.As<IEnumerable<SaleGoodsCategoryDto>>();
        }
        #endregion

        #region 获取销售商品分类分页
        public PageableList<SaleGoodsCategoryDto> Query(long? saleGoodsCategoryId, bool? enabled, DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(key, saleGoodsCategoryId, enabled, start, end, sortName, ascending, pageIndex, pageSize);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.saleGoodsCategoryData.Query(saleGoodsCategoryId, enabled, start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
                return new PageableList<SaleGoodsCategoryDto>
                {
                    Count = data.Item2,
                    Items = data.Item1.As<IEnumerable<SaleGoodsCategoryDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now
                };
            }, TimeSpan.FromMinutes(30));

            return result;
        }
        #endregion

        #region 启用销售商品分类
        public bool Enabled(long saleGoodsCategoryId)
        {
            if (!this.Exists(saleGoodsCategoryId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var result = this.saleGoodsCategoryData.Enabled(saleGoodsCategoryId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, saleGoodsCategoryId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 禁用销售商品分类
        public bool Disabled(long saleGoodsCategoryId)
        {
            if (!this.Exists(saleGoodsCategoryId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var result = this.saleGoodsCategoryData.Disabled(saleGoodsCategoryId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, saleGoodsCategoryId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 获取生成静态页面的商品分类列表
        public IEnumerable<SaleGoodsCategoryDto> GetMakeStaticPageListForSaleGoodsCategory(int size)
        {
            var result = this.saleGoodsCategoryData.GetList(size).GetAwaiter().GetResult();
            if(result.IsNotNull())
            {
                return result.As<IEnumerable<SaleGoodsCategoryDto>>();
            }
            else
            {
                return null;
            }
        }
        #endregion

    }
}